package cn.ztydata.teachingsystem.heaven.dao.redis;

import cn.ztydata.teachingsystem.heaven.cons.StudentAnswerStatus;
import cn.ztydata.teachingsystem.heaven.entity.test.StudentAnswer;
import cn.ztydata.teachingsystem.heaven.entity.test.TestExercise;
import com.google.common.collect.Lists;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.dao.DataAccessException;
import org.springframework.data.redis.core.HashOperations;
import org.springframework.data.redis.core.RedisOperations;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.core.SessionCallback;
import org.springframework.stereotype.Repository;

import javax.annotation.Resource;
import java.util.List;
import java.util.Map;

/**
 * 学生答题dao->redis类
 * Created by chenxin on 2015/04/14.
 */
@Repository
public class StudentAnswerRedisDao {
    protected static Logger logger = LoggerFactory.getLogger(StudentAnswerRedisDao.class); //日志记录器

    @Resource(name = "stringRedisTemplate")
    protected RedisTemplate redisTemplate; //sdr-Redis模版

    private static final String KEY_NAME = "student:answer";

    public static final String ANSWER_STATUS = "answerStatus"; //答题状态
    public static final String ANSWER_SCORE = "answerScore"; //答题得分
    public static final String ANSWER_CONTENT = "answerContent"; //答题内容
    public static final String ANSWER_COMMENT = "answerComment"; // 教师评语

    /**
     * 批量保存学生答题
     *
     * @param studentAnswerList 学生答题集合
     * @return boolean
     *
     * @author cx
     * @since 2015/4/14
     */
    public void saveStudentAnswers(final List<StudentAnswer> studentAnswerList) {
        //获取hash操作
        SessionCallback<Boolean> sessionCallback = new SessionCallback<Boolean>() {
            @Override
            public Boolean execute(RedisOperations kvRedisOperations) throws DataAccessException {
                kvRedisOperations.multi();

                //获取hash操作
                HashOperations<String, String, String> hashOperations = kvRedisOperations.opsForHash();

                logger.debug("循环学生答题集合");
                for (StudentAnswer studentAnswer : studentAnswerList) {
                    String key = KeyUtils.generateKey(KEY_NAME, studentAnswer.getStudentId(), studentAnswer.getTestId(), studentAnswer.getExerciseId());

                    Integer answerStatus = studentAnswer.getStatus();
                    Integer answerScore = studentAnswer.getScore();
                    String answerContent = studentAnswer.getAnswerContent();

                    hashOperations.put(key, ANSWER_STATUS, answerStatus.toString());
                    hashOperations.put(key, ANSWER_SCORE, answerScore.toString());
                    hashOperations.put(key, ANSWER_CONTENT, answerContent == null ? "" : answerContent);
                }

                kvRedisOperations.exec();

                logger.debug("批量保存学生答题");
                return true;
            }
        };

        redisTemplate.execute(sessionCallback);
    }

    /**
     * 查询单个学生答题记录
     * 
     * @param studentId 学生ID
     * @param testId 作业ID
     * @param exerciseId 习题ID
     * @return studentAnswer
     * 
     * @author cx
     * @since 2015/4/14
     */
    public StudentAnswer getStudentAnswer(final long studentId, final long testId, final long exerciseId) {
        //获取hash操作
        HashOperations<String, String, String> hashOperations = redisTemplate.opsForHash();

        String key = KeyUtils.generateKey(KEY_NAME, studentId, testId, exerciseId);
        //获取学生答题信息
        Map<String, String> entries = hashOperations.entries(key);

        StudentAnswer studentAnswer = new StudentAnswer(studentId, testId, exerciseId);

        mapper(studentAnswer, entries);

        logger.debug("查询单个学生答题记录");
        return studentAnswer;
    }

    /**
     * 查询学生作业的答题情况
     * 
     * @param studentId 学生ID
     * @param testExercises 作业习题集合
     * @return List
     * 
     * @author cx
     * @since 2015/4/14
     */
    public List<StudentAnswer> getStudentAnswers(final long studentId, final List<TestExercise> testExercises) {
        //获取hash操作
        HashOperations<String, String, String> hashOperations = redisTemplate.opsForHash();
        List<StudentAnswer> studentAnswers = Lists.newArrayList();

        logger.debug("循环作业习题集合");
        for (TestExercise testExercise : testExercises) {
            long testId = testExercise.getTestId();
            long exerciseId = testExercise.getExerciseId();
            String key = KeyUtils.generateKey(KEY_NAME, studentId, testId, exerciseId);
            Map<String, String> entries = hashOperations.entries(key);

            if (entries != null) {
                logger.debug("学生答题记录非null:entries != null");

                StudentAnswer studentAnswer = new StudentAnswer(studentId, testId, exerciseId);
                mapper(studentAnswer, entries);
                studentAnswers.add(studentAnswer);
            }
        }

        logger.debug("查询学生作业的答题情况");
        return studentAnswers;
    }

    /**
     * 装载学生作业习题的答题状态
     * @param studentId 学生ID
     * @param testExercises 作业习题集合
     *
     * @author cx
     * @since 2015/4/14
     */
    public void setStudentAnswerStatus(final long studentId, final List<TestExercise> testExercises) {
        //获取hash操作
        HashOperations<String, String, String> hashOperations = redisTemplate.opsForHash();

        for (TestExercise testExercise : testExercises) {
            long testId = testExercise.getTestId();
            long exerciseId = testExercise.getExerciseId();

            String key = KeyUtils.generateKey(KEY_NAME, studentId, testId, exerciseId);
            String answerStatus = hashOperations.get(key, ANSWER_STATUS);

            testExercise.setAnswerStatus(answerStatus == null ? StudentAnswerStatus.NOT_ANSWER : Integer.valueOf(answerStatus));
        }
    }

    /**
     * 更新学生答题信息子项
     * 
     * @param studentId 学生ID
     * @param testId 作业ID
     * @param exerciseId 习题ID
     * @param item 子项名称
     * @param itemValue 子项值
     * 
     * @author cx
     * @since 2015/4/15
     */
    public void updateStudentAnswerItem(final long studentId, final long testId, final long exerciseId, final String item, final String itemValue) {
        //获取hash操作
        HashOperations<String, String, String> hashOperations = redisTemplate.opsForHash();
        String key = KeyUtils.generateKey(KEY_NAME, studentId, testId, exerciseId);
        
        hashOperations.put(key, item, itemValue);
    }

    /**
     * 查询多个学生的作业习题答题情况
     * 
     * @param studentIds 学生ID集合
     * @param testId 作业ID
     * @param exerciseId 习题集合
     * @return List
     * 
     * @author cx
     * @since 2015/4/15
     */
    public List<StudentAnswer> getStudentAnswers(final List<Long> studentIds, final long testId, final long exerciseId) {
        //获取hash操作
        HashOperations<String, String, String> hashOperations = redisTemplate.opsForHash();
        List<StudentAnswer> studentAnswers = Lists.newArrayList();

        for (long studentId : studentIds) {
            String key = KeyUtils.generateKey(KEY_NAME, studentId, testId, exerciseId);
            Map<String, String> entries = hashOperations.entries(key);

            if (entries != null) {
                StudentAnswer studentAnswer = new StudentAnswer(studentId, testId, exerciseId);

                mapper(studentAnswer, entries);

                studentAnswers.add(studentAnswer);
            }
        }

        return studentAnswers;
    }

    /**
     * 更新学生答题-用于批阅
     * 
     * @param studentAnswer 学生答题
     *                     
     * @author cx
     * @since 2015/4/15
     */
    public void updateForReadover(final StudentAnswer studentAnswer) {
        //获取hash操作
        HashOperations<String, String, String> hashOperations = redisTemplate.opsForHash();

        String key = KeyUtils.generateKey(KEY_NAME, studentAnswer.getStudentId(), studentAnswer.getTestId(), studentAnswer.getExerciseId());

        hashOperations.put(key, ANSWER_STATUS, studentAnswer.getStatus().toString());
        hashOperations.put(key, ANSWER_SCORE, studentAnswer.getScore().toString());
        hashOperations.put(key, ANSWER_COMMENT, studentAnswer.getTeacherComment() == null ? "" : studentAnswer.getTeacherComment());
    }

    private void mapper(StudentAnswer studentAnswer, Map<String, String> entries) {
        String answerStatus = entries.get(ANSWER_STATUS);
        String answerScore = entries.get(ANSWER_SCORE);

        studentAnswer.setStatus(answerStatus == null ? StudentAnswerStatus.NOT_ANSWER : Integer.valueOf(answerStatus));
        studentAnswer.setScore(answerScore == null ? 0 : Integer.valueOf(answerScore));
        studentAnswer.setAnswerContent(entries.get(ANSWER_CONTENT));
        studentAnswer.setTeacherComment(entries.get(ANSWER_COMMENT));
    }
}
